package com.shao.onlinepdf.service.impl;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.layout.font.FontProvider;
import com.shao.onlinepdf.entity.TDocument;
import com.shao.onlinepdf.mapper.TDocumentMapper;
import com.shao.onlinepdf.service.ITDocumentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.templateresolver.StringTemplateResolver;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;

/**
 * <p>
 * 文档表 服务实现类
 * </p>
 *
 * @author admin
 * @since 2021-09-06
 */
@Slf4j
@Service
public class TDocumentServiceImpl extends ServiceImpl<TDocumentMapper, TDocument> implements ITDocumentService {

    private final String fontDir = "static/font/";
    private final String[] fonts = {
            "arial.ttf", "arialbd.ttf", "msyh.ttf", "msyhbd.ttf"
    };
    private FontProvider fp;

    public TDocumentServiceImpl() {
        loadFont();
    }

    /**
     * 加载字体
     */
    private void loadFont(){
        fp = new FontProvider();
        // fp.addSystemFonts(); windows系统可以，在Linux系统中可能没有中文字体，所以不采用这种方式加载字体。
        for (String f : fonts) {
            String resource = fontDir + f;
            try {
                fp.addFont(ResourceUtil.readBytes(resource));
            } catch (RuntimeException e) {
                log.error("font resource loading fail:{}", resource);
            }
        }
    }

    @Override
    public void livePdf(JSONObject body, HttpServletResponse response) {
        String html = body.getString("html");
        String css = body.getString("css");
        String json = body.getString("json");
        if (StringUtils.isBlank(html)) {
            html = "<div></div>";
        }
        if (StringUtils.isNotBlank(css)) {
            html += "<style>" + css + "</style>";
        }
        OutputStream out = null;
        try{
            response.setContentType("application/pdf");
            out = response.getOutputStream();
            //模板转换
            if (StringUtils.isNotBlank(json)) {
                Object data = JSON.parse(json);
                Context context = new Context();
                context.setVariable("d", data);
                TemplateEngine engine = new TemplateEngine();
                engine.setTemplateResolver(new StringTemplateResolver());
                html = engine.process(html, context);
            }
            ConverterProperties properties = new ConverterProperties().setFontProvider(fp);
            HtmlConverter.convertToPdf(html, out, properties);
        }catch (IOException e) {
            log.error("io error", e);
        }catch (Throwable e) {
            StringBuffer error = new StringBuffer("<h1>Build error</h1>");
            error.append("<div style='color:red;'>").append(e).append("</div>");
            error.append("<p>StackTrace:</p>");
            error.append("<p>");
            for (StackTraceElement element : e.getStackTrace()) {
                error.append("at ").append(element).append("<br/>");
            }
            error.append("</p>");
            HtmlConverter.convertToPdf(error.toString(), out);
        }finally {
            IoUtil.close(out);
        }
    }
}
